package com.cug.smartranch.animal.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cug.smartranch.animal.admin.common.enums.DeleteEnum;
import com.cug.smartranch.animal.admin.dao.entity.Animal;
import com.cug.smartranch.animal.admin.dao.entity.AnimalHealth;
import com.cug.smartranch.animal.admin.dao.entity.AnimalLocation;
import com.cug.smartranch.animal.admin.dao.mapper.AnimalLocationMapper;
import com.cug.smartranch.animal.admin.dto.req.AnimalLocationSaveReqDTO;
import com.cug.smartranch.animal.admin.dto.resp.AnimalLocationQueryRespDTO;
import com.cug.smartranch.animal.admin.service.AnimalHealthService;
import com.cug.smartranch.animal.admin.service.AnimalLocationService;
import com.cug.smartranch.animal.admin.service.AnimalService;
import com.cug.smartranch.framework.exception.ClientException;
import com.cug.smartranch.framework.exception.ServiceException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 动物坐标业务逻辑实现层
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class AnimalLocationServiceImpl extends ServiceImpl<AnimalLocationMapper, AnimalLocation> implements AnimalLocationService {

    private final AnimalLocationMapper animalLocationMapper;
    private final AnimalService animalService;

    @Override
    public void createAnimalLocation(AnimalLocationSaveReqDTO requestParam) {
        log.info("AnimalLocationServiceImpl createAnimalLocation方法入参：{}",requestParam);
        //入参校验
        if(requestParam.getAnimalId()==null){
            throw new ClientException("动物id不能为空");
        }
        if(requestParam.getLatitude()==null){
            throw new ClientException("动物维度不能为空");
        }
        if(requestParam.getLatitude()==null){
            throw new ClientException("动物经度不能为空");
        }
        //入参逻辑校验
        if(requestParam.getLatitude().compareTo(BigDecimal.valueOf(-90.0))<0||requestParam.getLatitude().compareTo(BigDecimal.valueOf(90.0))>0){
            throw new ClientException("动物维度必须在-90到90之间");
        }
        if(requestParam.getLongitude().compareTo(BigDecimal.valueOf(-180.0))<0||requestParam.getLongitude().compareTo(BigDecimal.valueOf(180.0))>0){
            throw new ClientException("动物经度必须在-180到180之间");
        }
        //校验动物是否被删除
        animalService.checkAnimalDelete(requestParam.getAnimalId());
        //构建请求参数
        AnimalLocation location = AnimalLocation.builder()
                .animalId(requestParam.getAnimalId())
                .latitude(requestParam.getLatitude())
                .longitude(requestParam.getLongitude()).build();
        //新增动物坐标
        int insert = animalLocationMapper.insert(location);
        if(insert>0){
            return;
        }else{
            throw new ServiceException("动物坐标记录插入失败");
        }
    }

    /**
     * 查询某个动物近期100条坐标记录
     * @param animalId
     * @return 某个动物近期100条坐标记录
     */
    @Override
    public List<AnimalLocationQueryRespDTO> findAnimalHealth(Long animalId) {
        log.info("AnimalLocationServiceImpl findAnimalHealth方法请求参数为：{}",animalId);
        //入参判空
        if(animalId==null){
            throw new ClientException("动物id为空");
        }
        //校验动物是否被删除
        animalService.checkAnimalDelete(animalId);
        //构建查询条件
        LambdaQueryWrapper<AnimalLocation> queryWrapper= Wrappers.lambdaQuery(AnimalLocation.class);
        queryWrapper.eq(AnimalLocation::getAnimalId,animalId);
        queryWrapper.eq(AnimalLocation::getDelFlag, DeleteEnum.NORMAL);
        queryWrapper.orderByDesc(AnimalLocation::getCreateTime);
        Page<AnimalLocation> page = new Page<>(1, 100);
        List<AnimalLocation> list = animalLocationMapper.selectPage(page, queryWrapper).getRecords();
        List<AnimalLocationQueryRespDTO> resultList = list.stream().map(animalLocation -> {
            AnimalLocationQueryRespDTO respDTO = BeanUtil.toBean(animalLocation, AnimalLocationQueryRespDTO.class);
            return respDTO;
        }).collect(Collectors.toList());
        return resultList;
    }

    @Override
    public void createMockAnimalLocation(Long animalId) {
        //校验该动物是否被删除
        animalService.checkAnimalDelete(animalId);
        //校验该动物的坐标记录是否超过100条，如果超过就无需创建
        LambdaQueryWrapper<AnimalLocation> queryWrapper = Wrappers.lambdaQuery(AnimalLocation.class);
        queryWrapper.eq(AnimalLocation::getAnimalId, animalId);
        queryWrapper.eq(AnimalLocation::getDelFlag, DeleteEnum.NORMAL.getType());
        List<AnimalLocation> list = animalLocationMapper.selectList(queryWrapper);
        if (list.size() > 100) {
            throw new ClientException("动物坐标记录已经够多了，不用创建了~~~");
        }
        // 随机数生成器
        Random rand = new Random();
        // 存储动物坐标的列表
        List<AnimalLocation> animalLocations = new ArrayList<>();
        int i=1;
        while(true){
            Double x = 100.0 + rand.nextDouble() * 200;
            Double y = 100.0 + rand.nextDouble() * 200;
            // 获取当前日期
            Date currentDate = new Date();
            // 使用 Calendar 类
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(currentDate);
            // 将日期回退x天
            calendar.add(Calendar.DAY_OF_YEAR, -i);
            // 获取前x天的 Date 对象
            Date previousDate = calendar.getTime();
            AnimalLocation location = AnimalLocation.builder()
                    .animalId(animalId)
                    .latitude(BigDecimal.valueOf(x))
                    .longitude(BigDecimal.valueOf(y))
                    .createTime(previousDate)
                    .updateTime(previousDate)
                    .build();
            animalLocations.add(location);
            if(animalLocations.size()>100){
                break;
            }
        }
        boolean flag = saveBatch(animalLocations);
        if(!flag){
            throw new ClientException("创建坐标记录失败，请查看数据库数据是否有异常");
        }
    }
}
